定制现有的示例应用程序
对现有的示例应用程序进行调试和优化,以满足特定的用例要求。本节将指导您在运行 Canonical Ubuntu 的魔方派 3 目标设备上使用 Qualcomm® 智能多媒体产品 (QIMP) SDK 下载、构建、自定义源代码,从而完全控制应用程序行为并实现跨运行时环境的性能优化。
预构建的应用程序非常适合快速评估,而定制化开发可实现:
- 集成自己的模型、媒体或逻辑
- 针对特定运行时目标(CPU、GPU、NPU)优化性能
- 添加新功能或修改现有功能以符合您的用例
- 使用 GStreamer尝试不同的管道配置
- 从工作基线开始构建可用于生产环境的应用程序
前提条件
- Ubuntu 操作系统 已刷入。
- 具有适当权限的终端访问。
- 如果您之前没有安装过 PPA 包,请按照以下步骤进行安装。
git clone -b ubuntu_setup --single-branch https://github.com/rubikpi-ai/rubikpi-script.git
 cd rubikpi-script
 ./install_ppa_pkgs.sh
从源代码构建
按照以下步骤下载、配置和编译示例应用程序源代码。这样就可以根据需要修改应用程序行为并集成自定义逻辑。
1️⃣安装以下软件包以下载源代码。
sudo apt-add-repository -s ppa:ubuntu-qcom-iot/qcom-ppa
sudo apt-get install adreno-dev
sudo apt-get install gstreamer1.0-qcom-sample-apps-utils-dev
2️⃣构建依赖项
运行命令获取源代码编译所需的插件
sudo apt build-dep gst-plugins-qti-oss
3️⃣下载源代码
下载示例应用程序源代码
cd /home/ubuntu
sudo apt source gst-plugins-qti-oss
4️⃣示例应用程序代码详解
以 gst-ai-usb-camera-app 为例进行代码讲解。这是高通开发的基于 GStreamer 的 C 语言应用程序,用于演示如何将 USB 摄像头用于不同用途:
- 在显示器上显示实时视频
- 将视频保存到文件
- 通过 RTSP 流式传输视频
- 使用 AI 模型运行对象检测
gst-ai-usb-camera-app 的源代码在
cd gst-plugins-qti-oss/gst-sample-apps/gst-ai-usb-camera-app
详细信息
a: 头文件和常量
#include <glib-unix.h>
#include <stdio.h>
#include <gst/gst.h>
#include <linux/videodev2.h>
#include <sys/ioctl.h>
#include <json-glib/json-glib.h>
文件和常量提供以下支持:
- GLib:实用函数和主循环
- GStreamer:多媒体框架
- Video4Linux2 (V4L2):访问 USB 摄像头
- JSON-GLib:从 JSON 读取配置
然后我们定义默认值:
#define DEFAULT_WIDTH 1280
#define DEFAULT_HEIGHT 720
#define DEFAULT_FRAMERATE 30
#define DEFAULT_OUTPUT_FILENAME "/etc/media/video.mp4"
#define DEFAULT_IP "127.0.0.1"
#define DEFAULT_PORT "8900"
如果用户不提供自定义设置,则使用这些设置。
b. 应用程序上下文结构
GstCameraAppCtx
此结构保存应用程序的状态:
struct GstCameraAppCtx {
    GstElement *pipeline;
    GMainLoop *mloop;
    gchar *output_file;
    gchar *ip_address;
    gchar *port_num;
    gchar *enable_ml;
    gchar dev_video[16];
    enum GstSinkType sinktype;
    enum GstVideoFormat video_format;
    gint width;
    gint height;
    gint framerate;
};
GstAppOptions
此结构保存来自配置文件的用户定义选项:
typedef struct {
    gchar *file_path;
    gchar *model_path;
    gchar *labels_path;
    gchar *constants;
    gchar **snpe_layers;
    GstCameraSourceType camera_type;
    GstModelType model_type;
    GstYoloModelType yolo_model_type;
    gdouble threshold;
    gint delegate_type;
    gint snpe_layer_count;
    gboolean use_cpu;
    gboolean use_gpu;
    gboolean use_dsp;
} GstAppOptions;
c. 从 JSON 读取配置
函数parse_json() 读取配置文件,并将值设置到appctx和options。
配置示例:
{
  "width": 1280,
  "height": 720,
  "framerate": 30,
  "output": "waylandsink",
  "enable-object-detection": "TRUE",
  "yolo-model-type": "yolov8",
  "ml-framework": "tflite"
}
代码片段:
if (json_object_has_member(root_obj, "width")) {
    appctx->width = json_object_get_int_member(root_obj, "width");
}
此代码实现从配置文件读取摄像头分辨率宽度参数。
d. 查找 USB 摄像头
函数: find_usb_camera_node()
该函数循环遍历 /dev/video0 到 /dev/video63 来查找有效的 USB 摄像头。
while (idx < MAX_VID_DEV_CNT) {
    snprintf(appctx->dev_video, sizeof(appctx->dev_video), "/dev/video%d", idx);
    mFd = open(appctx->dev_video, O_RDWR);
    ioctl(mFd, VIDIOC_QUERYCAP, &v2cap);
    if (strcmp((const char *)v2cap.driver, "uvcvideo") == 0) {
        break;
    }
    idx++;
}
e. 创建 GStreamer 管道
函数: create_preview_pipe()
该函数根据输出类型(显示、文件或 RTSP)构建管道。
示例:实时预览
v4l2src → capsfilter → waylandsink
代码:
v4l2src = gst_element_factory_make("v4l2src", "v4l2src");
capsfilter = gst_element_factory_make("capsfilter", "capsfilter");
waylandsink = gst_element_factory_make("waylandsink", "waylandsink");
示例:保存到文件
v4l2src → capsfilter → qtivtransform → v4l2h264enc → h264parse → filesink
代码:
filesink = gst_element_factory_make("filesink", "filesink");
v4l2h264enc = gst_element_factory_make("v4l2h264enc", "v4l2h264enc");
h264parse = gst_element_factory_make("h264parse", "h264parse");
示例:RTSP 流式传输
v4l2src → capsfilter → qtivtransform → v4l2h264enc → h264parse → qtirtspbin
f. 对象检测管道
函数: create_pipe()
这将构建一个更复杂的管道,用于基于 AI 的对象检测。
管道流程:
v4l2src → capsfilter → tee → qtivcomposer → waylandsink
代码:
qtimlvconverter = gst_element_factory_make("qtimlvconverter", "qtimlvconverter");
qtimlelement = gst_element_factory_make("qtimltflite", "qtimlelement");
qtimlvdetection = gst_element_factory_make("qtimlvdetection", "qtimlvdetection");
qtivcomposer = gst_element_factory_make("qtivcomposer", "qtivcomposer");
插件功能如下:
预处理:qtimlvconverter
推理:qtimltflite, qtimlsnpe, or qtimlqnn
后处理:qtimlvdetection
叠加:qtivcomposer
g. 主函数
程序入口:
int main(int argc, char *argv[]) {
    appctx = gst_app_context_new();
    parse_json(config_file, &options, appctx);
    find_usb_camera_node(appctx);
    create_pipe(appctx, &options);
    gst_element_set_state(pipeline, GST_STATE_PAUSED);
    g_main_loop_run(appctx->mloop);
}
它的功能:
初始化应用程序上下文
读取配置文件
查找 USB 摄像头
构建管道
运行主循环
h. 用户可以根据以下内容来更新示例应用程序
- 根据上述解释
- 从 获取图片格式与尺寸 获取所连接 USB 摄像头支持的图像格式和大小的详细信息(通过yavta),并修改json或源代码。
5️⃣编 译示例应用程序工具以获取最新的头文件
cd gst-plugins-qti-oss/gst-sample-apps/gst-sample-apps-utils
mkdir build; cd build
cmake \
   -DGST_VERSION_REQUIRED=1.20.1 \
   -DSYSROOT_INCDIR=/usr/include \
   -DSYSROOT_LIBDIR=/usr/lib \
   -DGST_PLUGINS_QTI_OSS_INSTALL_BINDIR=/usr/bin \
   -DGST_PLUGINS_QTI_OSS_INSTALL_CONFIG=/etc/configs \
   -DENABLE_CAMERA=TRUE \
   -DENABLE_VIDEO_ENCODE=TRUE \
   -DENABLE_VIDEO_DECODE=TRUE \
   -DENABLE_DISPLAY=TRUE \
   -DENABLE_ML=TRUE \
   -DENABLE_AUDIO=TRUE \
   -DCAMERA_SERVICE=LECAM \
   -DGST_PLUGINS_QTI_OSS_INSTALL_INCDIR=/usr/include \
   ..
make
make install
6️⃣进入您想要修改的示例应用程序,应用您的更改并进行编译。此示例展示如何构建对象检测应用程序。
cd gst-plugins-qti-oss/gst-sample-apps/gst-ai-object-detection
mkdir build; cd build
cmake \
   -DGST_VERSION_REQUIRED=1.20.1 \
   -DSYSROOT_INCDIR=/usr/include \
   -DSYSROOT_LIBDIR=/usr/lib \
   -DGST_PLUGINS_QTI_OSS_INSTALL_BINDIR=/usr/bin \
   -DGST_PLUGINS_QTI_OSS_INSTALL_CONFIG=/etc/configs \
   -DENABLE_CAMERA=TRUE \
   -DENABLE_VIDEO_ENCODE=TRUE \
   -DENABLE_VIDEO_DECODE=TRUE \
   -DENABLE_DISPLAY=TRUE \
   -DENABLE_ML=TRUE \
   -DENABLE_AUDIO=TRUE \
   -DCAMERA_SERVICE=LECAM \
   -DGST_PLUGINS_QTI_OSS_INSTALL_INCDIR=/usr/include \
   ..
make
make install
每个示例应用程序都需要单独编译
7: 运行已编译的示例应用程序
gst-ai-usb-camera-app
要显示可用的帮助选项,请在 SSH shell 中运行以下命令:
gst-ai-usb-camera-app -h
按CTRL + C可停止用例。
参考文档:
AI developer workflow - Ubuntu on Qualcomm® IoT Platforms Documentation